<script setup lang="jsx">
import { useBoolean } from '@/hooks/useBoolean'
import { useTableDrag } from '@/hooks/useTableDrag'
import { fetchAllUser, updateUserState, deleteUser, updateUserRole, searchUser } from '@/service'
import { NButton, NPopconfirm, NSpace, NSwitch, NSelect } from 'naive-ui'
import Avatar from './components/Avatar.vue'

const { bool: loading, setTrue: startLoading, setFalse: endLoading } = useBoolean(false)

const formValue = ref({
  username: null,
  role: null
})
const userCount = ref(1)
const formRef = ref()
const roleOption = [
  {
    label: '超级管理员',
    value: '101'
  },
  {
    label: '超级用户',
    value: '102'
  },
  {
    label: 'WMS用户',
    value: '201'
  },
  {
    label: 'WMTS用户',
    value: '202'
  },
  {
    label: 'leaflet用户',
    value: '301'
  },
  {
    label: 'openlayers用户',
    value: '302'
  },
  {
    label: 'cesium用户',
    value: '303'
  },
  {
    label: 'webgl用户',
    value: '304'
  }
]

const columns = ref([
  {
    title: '头像',
    align: 'center',
    key: 'username',
    render: (row) => <Avatar key={row._id} uid={row._id} />
  },
  {
    title: '用户 ID',
    align: 'center',
    key: '_id'
  },
  {
    title: '用户名',
    align: 'center',
    key: 'username'
  },
  {
    title: '角色',
    align: 'center',
    key: 'role_name',
    width: 350,
    render: (row) => <NSelect value={row.role_name} onUpdate:value={(value, option) => handleSelection(value, option, row)} options={roleOption} />
  },
  {
    title: '注册时间',
    align: 'center',
    key: 'createTime'
  },
  {
    title: '状态',
    align: 'center',
    key: 'state',
    render: (row) => (
      <NSwitch rail-style={railStyle} value={row.state} checked-value={1} unchecked-value={0} onUpdateValue={(value) => handleUpdateDisabled(value, row._id)}>
        {{
          checked: () => '启用',
          unchecked: () => '禁用'
        }}
      </NSwitch>
    )
  },
  {
    title: '操作',
    align: 'center',
    key: 'actions',
    render: (row) => (
      <NSpace justify="center">
        <NPopconfirm onPositiveClick={() => deleteSelectedUser(row._id)}>
          {{
            default: () => '是否删除所选用户？',
            trigger: () => (
              <NButton strong secondary size="small" type="error">
                删除
              </NButton>
            )
          }}
        </NPopconfirm>
      </NSpace>
    )
  }
])
const listData = ref([])
const tableRef = ref()
const showPagination = ref(true)

onMounted(() => {
  getUserList()
})

useTableDrag({
  tableRef,
  data: listData,
  onRowDrag(data) {
    data[data.length - 1]
  }
})

function railStyle({ focused, checked }) {
  const style = {}
  if (!checked) {
    style.background = '#d03050'
    if (focused) style.boxShadow = '0 0 0 2px #d0305040'
  }
  return style
}

async function handleSelection(value, option, row) {
  await updateUserRole(row._id, value)
    .then(() => {
      const index = listData.value.findIndex((item) => item._id === row._id)
      if (index > -1) listData.value[index].role_name = option.label
      window.$message.success(`修改用户 ${row.username} 的角色为 ${option.label} 成功`)
    })
    .catch((error) => {
      window.$message.error(`修改出错：${error}`)
    })
}

async function handleUpdateDisabled(value, id) {
  await updateUserState(id, value)
    .then(() => {
      const index = listData.value.findIndex((item) => item._id === id)
      if (index > -1) listData.value[index].state = value
      window.$message.success(`设置用户 ${id} 的状态为 ${value ? '启用' : '禁用'} 成功`)
    })
    .catch((error) => {
      window.$message.error(`修改出错：${error}`)
    })
}

async function deleteSelectedUser(id) {
  await deleteUser(id)
    .then(() => {
      listData.value = listData.value.filter((item) => item._id !== id)
      window.$message.success(`删除id为: ${id} 的用户成功`)
    })
    .catch((error) => {
      window.$message.error(`删除出错：${error}`)
    })
}

async function getUserList() {
  startLoading()
  await fetchAllUser()
    .then((res) => {
      listData.value = res.data.itemData
      listData.value.forEach((item) => {
        item.createTime = formatDateTime(item.createTime)
      })
      showPagination.value = res.data.isPagination
      userCount.value = parseInt(res.data.total)
      endLoading()
    })
    .catch((error) => {
      window.$message.error(error)
    })
}

async function changePage(page, size) {
  startLoading()
  await fetchAllUser(page, size)
    .then((res) => {
      listData.value = res.data.itemData
      listData.value.forEach((item) => {
        item.createTime = formatDateTime(item.createTime)
      })
      showPagination.value = res.data.isPagination
      endLoading()
    })
    .catch((error) => {
      window.$message.error(error)
    })
}

// 将 ISO 字符串转换为常用格式
function formatDateTime(isoString) {
  const date = new Date(isoString)
  return date.toLocaleString()
}

async function queryUserList() {
  if ((formValue.value.username === null || formValue.value.username?.trim() === '') && (formValue.value.role === null || formValue.value.role?.trim() === '')) return window.$message.info('请输入查询信息')
  startLoading()
  await searchUser({ username: formValue.value.username, role_name: formValue.value.role })
    .then((res) => {
      listData.value = res.data.itemData
      listData.value.forEach((item) => {
        item.createTime = formatDateTime(item.createTime)
      })
      showPagination.value = res.data.isPagination
      endLoading()
      window.$message.success('查询成功')
    })
    .catch((error) => {
      window.$message.error(error)
    })
}

function handleResetSearch() {
  formValue.value = { username: null, role: null }
  getUserList()
}
</script>

<template>
  <NSpace vertical size="large">
    <n-card>
      <n-form ref="formRef" :model="formValue" label-placement="left" inline :show-feedback="false">
        <n-flex>
          <n-form-item label="用户名" path="username">
            <n-input v-model:value="formValue.username" placeholder="请输入" />
          </n-form-item>
          <n-form-item label="角色" path="role">
            <n-input v-model:value="formValue.role" placeholder="请输入" />
          </n-form-item>
          <n-flex class="ml-auto">
            <NButton :loading="loading" type="primary" @click="queryUserList">
              <template #icon>
                <icon-park-outline-search />
              </template>
              搜索
            </NButton>
            <NButton strong secondary @click="handleResetSearch">
              <template #icon>
                <icon-park-outline-redo />
              </template>
              重置
            </NButton>
          </n-flex>
        </n-flex>
      </n-form>
    </n-card>
    <n-card>
      <NSpace vertical size="large">
        <n-data-table striped ref="tableRef" row-class-name="drag-handle" :columns="columns" :data="listData" :loading="loading" :remote="true" />
        <Pagination v-if="showPagination" :count="userCount" @change="changePage" />
      </NSpace>
    </n-card>
  </NSpace>
</template>
